package com.chris.oauth2.web;

import java.util.List;
import java.util.Random;

import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.chris.oauth2.Client;
import com.chris.oauth2.JsonResult;
import com.chris.oauth2.service.AuthService;
import com.chris.oauth2.service.ClientService;
import com.chris.oauth2.util.IdUtil;
import com.chris.oauth2.util.MD5Util;

@Controller
public class IndexController {

	@Autowired
	AuthService authService;
	@Autowired
	ClientService clientService;

	@RequestMapping("admin")
	public ModelAndView index(HttpSession session) {
		ModelAndView mav = new ModelAndView();
		if (!isLogin(session)) {
			mav.setViewName("forward:/login");
			return mav;
		}
		Client client = (Client) session.getAttribute("client");
		mav.addObject("client", client);
		mav.setViewName("index");
		return mav;
	}

	@RequestMapping("clients")
	public ModelAndView clients(HttpSession session) {
		ModelAndView mav = new ModelAndView();
		if (!isLogin(session)) {
			mav.setViewName("forward:/login");
			return mav;
		}
		mav.setViewName("clients");
		return mav;
	}

	@RequestMapping("createClient")
	public ModelAndView createClient(HttpSession session) {
		ModelAndView mav = new ModelAndView();
		if (!isLogin(session)) {
			mav.setViewName("forward:/login");
			return mav;
		}
		mav.setViewName("createClient");
		return mav;
	}

	@RequestMapping("create")
	@Transactional
	public ModelAndView create(HttpSession session, @RequestParam String name, @RequestParam String username,
			@RequestParam String password) {
		ModelAndView mav = new ModelAndView();
		if (!isLogin(session)) {
			mav.setViewName("forward:/login");
			return mav;
		}
		if (!isAdmin(session)) {
			mav.setViewName("forward:/login");
			return mav;
		}
		Client client = new Client();
		client.setName(name);
		client.setUsername(username);
		client.setPassword(password);
		client.setCid(IdUtil.generateId());
		client.setSecret(MD5Util.encode((client.getCid() + IdUtil.generateId()).getBytes()));
		client = clientService.createClient(client);
		mav.setViewName("createClient");
		return mav;
	}

	@RequestMapping("changePassword")
	@Transactional
	public @ResponseBody JsonResult updateClient(HttpSession session, @RequestParam String password) {
		if (!isLogin(session)) {
			return new JsonResult(201, "no login");
		}
		Client client = (Client) session.getAttribute("client");
		client.setPassword(password);
		clientService.updateClient(client);
		return new JsonResult(0, client);
	}

	@RequestMapping("resetPassword")
	@Transactional
	public @ResponseBody JsonResult resetPassword(HttpSession session, @RequestParam long id) {
		if (!isLogin(session)) {
			return new JsonResult(201, "no login");
		}
		if (!isAdmin(session)) {
			return new JsonResult(201, "permission denied");
		}
		Client client = clientService.findOne(id);
		int abs = Math.abs(new Random().nextInt());
		String password;
		if (abs > 1000000) {
			password = ("" + abs).substring(0, 6);
		} else {
			password = StringUtils.rightPad("" + abs, 6, "0");
		}
		client.setPassword(password);
		clientService.updateClient(client);
		return new JsonResult(0, password);
	}

	@RequestMapping("changeSecret")
	@Transactional
	public @ResponseBody JsonResult changeSecret(HttpSession session,
			@RequestParam(required = false, defaultValue = "-1") long id) {
		if (!isLogin(session)) {
			return new JsonResult(201, "no login");
		}
		if (id < 0) {// self
			Client client = (Client) session.getAttribute("client");
			String secret = IdUtil.generateId();
			client.setSecret(secret);
			clientService.updateClient(client);

			return new JsonResult(0, secret);
		} else {// admin
			if (!isAdmin(session)) {
				return new JsonResult(201, "permission denied");
			}
			Client client = clientService.findOne(id);
			String secret = IdUtil.generateId();
			client.setSecret(secret);
			clientService.updateClient(client);
			return new JsonResult(0, secret);
		}
	}

	@RequestMapping("delete")
	@Transactional
	public @ResponseBody JsonResult deleteClient(HttpSession session, @RequestParam long id) {
		if (!isLogin(session)) {
			return new JsonResult(201, "no login");
		}
		if (!isAdmin(session)) {
			return new JsonResult(201, "permission denied");
		}
		Client client = clientService.findOne(id);
		clientService.deleteClient(id);
		authService.clear(client.getCid());
		return new JsonResult(0);
	}

	@RequestMapping("list")
	public @ResponseBody JsonResult listClients(HttpSession session) {
		if (!isLogin(session)) {
			return new JsonResult(201, "no login");
		}
		if (!isAdmin(session)) {
			return new JsonResult(201, "permission denied");
		}
		List<Client> data = clientService.findAll();
		return new JsonResult(0, data);
	}

	private boolean isLogin(HttpSession session) {
		Object a = session.getAttribute("client");
		return a != null;
	}

	private boolean isAdmin(HttpSession session) {
		Object a = session.getAttribute("isAdmin");
		return a != null && (boolean) a;
	}
}
